package com.ligy.ui;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class GameFrame extends JFrame implements KeyListener, ActionListener {

    int[] initData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    int[][] data = new int[4][4];

    int x = 0;
    int y = 0;

    private String path = "image/animal/animal2/";

    private Boolean showing = false;

    private final static int[][] winData = {
            {1, 2, 3, 4,},
            {5, 6, 7, 8,},
            {9, 10, 11, 12,},
            {13, 14, 15, 0}
    };
    private static boolean gameState = false;

    // 菜单
    JMenuItem reStart = new JMenuItem("重新开始");
    JMenuItem reLoginItem = new JMenuItem("重新登陆");
    JMenuItem exitGameItem = new JMenuItem("退出游戏");
    JMenuItem aboutItem = new JMenuItem("公众号");

    // 更换图片菜单
    JMenuItem girlItem = new JMenuItem("美女");
    JMenuItem animalItem = new JMenuItem("动物");
    JMenuItem sportItem = new JMenuItem("运动");

    // 计步器
    private int count = 0;

    public GameFrame() {
        gameState = true;
        // 初始化界面
        initJFrame();

        // 初始化菜单
        initMenu();

        // 初始化数据
        initData();

        // 初始化图片
        initImage();

        this.setVisible(true);
    }

    private void initData() {
        Random rand = new Random();
        for (int i = 0; i < initData.length; i++) {
            int index = rand.nextInt(initData.length);
            int temp = initData[i];
            initData[i] = initData[index];
            initData[index] = temp;
        }

        for (int i = 0; i < initData.length; i++) {
            data[i / 4][i % 4] = initData[i];

            // 记录0 的位置
            if (initData[i] == 0) {
                x = i / 4;
                y = i % 4;
            }
        }
    }

    private void initImage() {
        // 清空所有内容
        this.getContentPane().removeAll();

        JLabel countText = new JLabel("步数：" + count);
        countText.setBounds(40, 30, 100, 30);
        this.getContentPane().add(countText);

        if (victory()) {
            JLabel jLabel = new JLabel(new ImageIcon("image/win.png"));
            jLabel.setBounds(203, 283, 197, 73);
            this.getContentPane().add(jLabel);
            gameState = false;
        }

        int imgSize = 105;

        // 添加每一小块图片
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // 创建图片对象
                ImageIcon image = new ImageIcon(path + data[i][j] + ".jpg");

                // 创建图片容器
                JLabel jLabel = new JLabel(image);

                // 设置位置
                jLabel.setBounds(imgSize * j + 83, imgSize * i + 134, imgSize, imgSize);

                // 设置边框
                jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));

                // 将容器放入到界面中
                this.getContentPane().add(jLabel);
            }
        }

        // 添加背景图
        JLabel bg = new JLabel(new ImageIcon("image/background.png"));
        bg.setBounds(40, 40, 508, 560);
        this.getContentPane().add(bg);

        // 重新绘制
        this.getContentPane().repaint();
    }

    private void initMenu() {
        JMenuBar jMenuBar = new JMenuBar();

        JMenu functionMenuBar = new JMenu("功能");
        JMenu aboutMenuBar = new JMenu("关于");

        JMenu changeImage = new JMenu("更换图片");

        // 将菜单加入对应项
        functionMenuBar.add(changeImage);
        functionMenuBar.add(reStart);
        functionMenuBar.add(reLoginItem);
        functionMenuBar.add(exitGameItem);
        aboutMenuBar.add(aboutItem);
        jMenuBar.add(functionMenuBar);
        jMenuBar.add(aboutMenuBar);
        aboutMenuBar.add(aboutItem);
        changeImage.add(girlItem);
        changeImage.add(animalItem);
        changeImage.add(sportItem);


        // 绑定点击事件
        reStart.addActionListener(this);
        reLoginItem.addActionListener(this);
        exitGameItem.addActionListener(this);
        aboutItem.addActionListener(this);
        girlItem.addActionListener(this);
        animalItem.addActionListener(this);
        sportItem.addActionListener(this);

        this.setJMenuBar(jMenuBar);
    }

    private void initJFrame() {
        this.setSize(603, 680);

        this.setTitle("拼图小游戏 单机版v1.0");

        // 设置关闭窗口自动停止程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 设置
        this.setLocationRelativeTo(null);

        // 设置置顶窗口
        this.setAlwaysOnTop(true);

        // 取消默认排列方式
        this.setLayout(null);

        // 绑定键盘事件
        this.addKeyListener(this);
    }

    /**
     * 释放
     *
     * @param e the event to be processed
     */
    @Override
    public void keyReleased(KeyEvent e) {
        if (!gameState) {
            return;
        }
        int code = e.getKeyCode();

        switch (code) {
            case KeyEvent.VK_UP: {
                moveBlock(x + 1, y);
                break;
            }
            case KeyEvent.VK_DOWN: {
                moveBlock(x - 1, y);
                break;
            }
            case KeyEvent.VK_LEFT: {
                moveBlock(x, y + 1);
                break;
            }
            case KeyEvent.VK_RIGHT: {
                moveBlock(x, y - 1);
                break;
            }
            case KeyEvent.VK_A: {
                showing = false;
                initImage();
                break;
            }
            case KeyEvent.VK_W: {
                this.data = winData;
                initImage();
                break;
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    /**
     * 按下触发，长按就一直触发
     *
     * @param e the event to be processed
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if (!gameState) {
            return;
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            if (showing) {
                return;
            }
            showing = true;

            JLabel jLabel = new JLabel(new ImageIcon(path + "all.jpg"));

            jLabel.setBounds(83, 134, 420, 420);

            this.getContentPane().removeAll();

            this.getContentPane().add(jLabel);

            // 添加背景图
            JLabel bg = new JLabel(new ImageIcon("image/background.png"));
            bg.setBounds(40, 40, 508, 560);
            this.getContentPane().add(bg);

            this.getContentPane().repaint();
        }
    }

    /**
     * 移动方块
     */
    private void moveBlock(int targetX, int targetY) {
        if (targetX < 0 || targetX > 3 || targetY < 0 || targetY > 3) {
            return;
        }
        count++;
        data[x][y] = data[targetX][targetY];
        data[targetX][targetY] = 0;
        x = targetX;
        y = targetY;
        initImage();
    }


    /**
     * 判断胜利
     */
    private boolean victory() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (winData[i][j] != data[i][j]) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * 菜单操作
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();

        // 重新开始游戏
        if (source == reStart) {
            count = 0;
            initData();
            initImage();
        }
        // 重新登录
        else if (source == reLoginItem) {
            // 关闭当前窗口
            this.setVisible(false);

            // 打开登录窗口
            new LoginJFrame();
        }
        // 退出游戏
        else if (source == exitGameItem) {
            System.exit(0);
        }
        // 打开关于我们
        else if (source == aboutItem) {
            JDialog aboutDialog = new JDialog();

            JLabel jLabel = new JLabel(new ImageIcon("image/about.png"));
            jLabel.setBounds(0, 0, 258, 258);
            aboutDialog.getContentPane().add(jLabel);
            aboutDialog.setSize(344, 344);
            aboutDialog.setLocationRelativeTo(null);
            aboutDialog.setModal(true);
            aboutDialog.setAlwaysOnTop(true);
            aboutDialog.setVisible(true);
        }
        // 判断点击 girl
        else if(source == girlItem) {
            initData();
            Random rand = new Random();
            path = "image/girl/girl" + rand.nextInt(1, 14) + "/";
            count = 0;
            initImage();
        }
        // 点击动物
        else if(source == animalItem) {
            initData();
            Random rand = new Random();
            path = "image/animal/animal" + rand.nextInt(1, 9) + "/";
            count = 0;
            initImage();
        }
        // 点击运动
        else if(source == sportItem) {
            initData();
            Random rand = new Random();
            path = "image/sport/sport" + rand.nextInt(1, 11) + "/";
            count = 0;
            initImage();
        }
    }
}
